<template>
  <view class="video-cover-container" :style="{ width: width, height: height }">
    <!-- 已截取封面 -->
    <image
      v-if="coverUrl"
      :src="coverUrl"
      :mode="mode"
      class="cover-image"
      @error="onImageError"
    />

    <!-- 加载中 -->
    <view v-else-if="loading" class="cover-loading">
      <text class="loading-icon">⏳</text>
      <text class="loading-text">加载中...</text>
    </view>

    <!-- 占位图 -->
    <view v-else class="cover-placeholder">
      <text class="placeholder-icon">🎬</text>
    </view>

    <!-- 隐藏的 video 用于截帧（仅 H5） -->
    <!-- #ifdef H5 -->
    <video
      v-if="videoUrl && !coverUrl && needCapture"
      :src="videoUrl"
      :id="videoId"
      class="hidden-video"
      :show-center-play-btn="false"
      :controls="false"
      :autoplay="false"
      :muted="true"
      :preload="'metadata'"
      crossorigin="anonymous"
      @loadeddata="onVideoLoaded"
      @error="onVideoError"
    />
    <canvas
      :id="canvasId"
      class="hidden-canvas"
      :style="{ width: captureWidth + 'px', height: captureHeight + 'px' }"
    />
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  name: "VideoCover",
  props: {
    // 视频地址
    videoUrl: {
      type: String,
      default: "",
    },
    // 封面图地址（如果已有）
    poster: {
      type: String,
      default: "",
    },
    // 宽度
    width: {
      type: String,
      default: "100%",
    },
    // 高度
    height: {
      type: String,
      default: "300rpx",
    },
    // 图片模式
    mode: {
      type: String,
      default: "aspectFill",
    },
    // 是否自动截取
    autoCapture: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      coverUrl: "",
      loading: false,
      needCapture: false,
      videoId: "video-" + Date.now() + Math.random(),
      canvasId: "canvas-" + Date.now() + Math.random(),
      captureWidth: 400,
      captureHeight: 300,
    };
  },
  watch: {
    videoUrl: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.loadCover();
        }
      },
    },
    poster: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.coverUrl = newVal;
        }
      },
    },
  },
  methods: {
    // 加载封面
    async loadCover() {
      if (this.poster) {
        this.coverUrl = this.poster;
        return;
      }

      if (!this.videoUrl || !this.autoCapture) {
        return;
      }

      // 检查缓存
      const cacheKey = "video_cover_" + this.videoUrl;
      const cached = uni.getStorageSync(cacheKey);
      if (cached) {
        this.coverUrl = cached;
        return;
      }

      // #ifdef H5
      // H5 环境尝试截取
      this.needCapture = true;
      this.loading = true;
      // #endif

      // #ifndef H5
      // 非 H5 环境使用视频地址作为封面（video 组件会显示第一帧）
      this.coverUrl = this.videoUrl;
      // #endif
    },

    // 视频加载完成（H5）
    onVideoLoaded() {
      // #ifdef H5
      this.$nextTick(() => {
        this.captureFrame();
      });
      // #endif
    },

    // 截取视频帧（H5）
    captureFrame() {
      // #ifdef H5
      try {
        const video = document.getElementById(this.videoId);
        if (!video) {
          console.error("未找到 video 元素");
          this.loading = false;
          this.useFallback();
          return;
        }

        // 等待视频可以播放
        setTimeout(() => {
          try {
            const canvas = document.getElementById(this.canvasId);
            if (!canvas) {
              console.error("未找到 canvas 元素");
              this.loading = false;
              this.useFallback();
              return;
            }

            // 设置 canvas 尺寸
            const width = video.videoWidth || this.captureWidth;
            const height = video.videoHeight || this.captureHeight;

            if (width === 0 || height === 0) {
              console.warn("视频尺寸为 0，使用降级方案");
              this.loading = false;
              this.useFallback();
              return;
            }

            canvas.width = width;
            canvas.height = height;

            const ctx = canvas.getContext("2d");

            // 绘制视频帧
            ctx.drawImage(video, 0, 0, width, height);

            // 转换为 base64（可能因跨域失败）
            try {
              const imageData = canvas.toDataURL("image/jpeg", 0.8);
              this.coverUrl = imageData;
              this.loading = false;
              this.needCapture = false;

              // 缓存结果
              const cacheKey = "video_cover_" + this.videoUrl;
              uni.setStorageSync(cacheKey, imageData);

              // 触发截取成功事件
              this.$emit("captured", imageData);
            } catch (error) {
              // 跨域错误，使用降级方案
              console.warn("视频跨域限制，无法生成封面:", error.message);
              this.loading = false;
              this.useFallback();
            }
          } catch (error) {
            console.error("Canvas 操作失败:", error);
            this.loading = false;
            this.useFallback();
          }
        }, 500);
      } catch (error) {
        console.error("截取视频帧失败:", error);
        this.loading = false;
        this.useFallback();
      }
      // #endif
    },

    // 使用降级方案
    useFallback() {
      // 使用视频地址本身（某些环境下 image 组件可以显示视频第一帧）
      // 或者显示占位图
      this.needCapture = false;
      // 不设置 coverUrl，让占位图显示
    },

    // 视频加载错误
    onVideoError(e) {
      console.error("视频加载失败:", e);
      this.loading = false;
      this.needCapture = false;
      this.$emit("error", e);
    },

    // 图片加载错误
    onImageError(e) {
      console.error("封面图加载失败:", e);
      // 降级为占位图
      this.coverUrl = "";
      this.$emit("error", e);
    },
  },
};
</script>

<style scoped>
.video-cover-container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.3);
}

.cover-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cover-loading,
.cover-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.1) 0%,
    rgba(236, 72, 153, 0.1) 100%
  );
}

.loading-icon,
.placeholder-icon {
  font-size: 60rpx;
  margin-bottom: 20rpx;
  display: block;
}

.loading-text {
  font-size: 24rpx;
  color: rgba(255, 255, 255, 0.6);
  display: block;
}

/* 隐藏用于截帧的元素 */
.hidden-video,
.hidden-canvas {
  position: fixed;
  top: -9999px;
  left: -9999px;
  width: 1px !important;
  height: 1px !important;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
</style>
